home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 January: Mac OS SDK / Dev.CD Jan 96 SDK / Dev.CD Jan 96 SDK1.toast / Development Kits (Disc 1) / AppleScript / Development Tools / Sample Code / 7Edit / Pascal Sources / SVEditUtils.p < prev    next >
Encoding:
Text File  |  1994-02-25  |  20.9 KB  |  729 lines  |  [TEXT/MPS ]

  1. {[d-,h-,k+,o=100,q+,r+,rec+,t=2,u+,:+,j=15/20/25/30/35/40/45/50/57/1$]} {Pasmat opts!}
  2.  
  3. UNIT SVEditUtils;
  4. (*
  5.     SVEditUtils.p
  6.     
  7.     Version 3.0d8
  8.     
  9.     Copyright © SRL Data 1992, 1993
  10.     
  11.     All rights reserved
  12.     
  13.     Produced by : SRL Data
  14.     Originally Developed for UK.DTS
  15. *)
  16.  
  17.     This example is brought to you for the purposes of exploration and experimentation of
  18.     System 7.0.  It is not intended to form the basis of your own programs - but try out the code-
  19.     that's what it's there for 
  20.     
  21.     New for 3.0d2:
  22.     
  23.     19-Feb-92 : NH : Grey Page Setup when no window
  24.     27-Feb-92 : NH : Remove test menu, gCurrSection
  25.     18-Mar-92 : NH : Add GreaterOf
  26.                      Change DrawDefaultOutline
  27.                                      Comments added
  28.     27-Mar-92 : NH : Arrow cursor before alerts
  29.     
  30.     New for 3.0d3:
  31.     
  32.     24-Jun-92 : NH : Deleted unused variables in CheckEnvironment
  33.     26-Jun-92 : NH : AEInteractWithUser before Alert
  34.     
  35.     New for 3.0d5:
  36.     
  37.     21-Aug-92 : NH : TEContinuousStyle used
  38.         
  39. }
  40.  
  41.   INTERFACE
  42.  
  43.     USES MemTypes,
  44.                  QuickDraw,
  45.                  OSIntf,
  46.                  OSUtils,
  47.                  ToolIntf,
  48.                  Traps,
  49.                  Packages,
  50.                  GestaltEqu,
  51.                  Editions,
  52.          printing,
  53.                  SVEditGlobals;
  54.  
  55.       {new routines for 7Edit}
  56.  
  57.     FUNCTION GestaltAvailable: BOOLEAN;
  58.  
  59.     FUNCTION CheckEnvironment: BOOLEAN;
  60.  
  61.     PROCEDURE ShowError(theError: STR255;
  62.                         theErrorCode: LONGINT);
  63.  
  64.     FUNCTION FeatureIsImplemented(theFeature: OSType;
  65.                                   theTestBit: INTEGER): BOOLEAN;
  66.  
  67.     PROCEDURE GetTempFileName(aDoc: DPtr;
  68.                               VAR newString: STR255);
  69.  
  70.     FUNCTION Ours(aWindow: WindowPtr): BOOLEAN;
  71.  
  72.     PROCEDURE SetShortMenus;
  73.  
  74.     PROCEDURE SetLongMenus;
  75.  
  76.     PROCEDURE SetStyleMenu(theDoc: DPtr);
  77.  
  78.     PROCEDURE SetFontMenu(theDoc: DPtr);
  79.         
  80.         PROCEDURE SetEditMenu(theDoc: DPtr);
  81.  
  82.     PROCEDURE AdornDefaultButton(theDialog: DialogPtr; theItem:INTEGER);
  83.         
  84.         PROCEDURE DrawDefaultOutline(theDialog:DialogPtr; theItem:INTEGER);
  85.  
  86.     PROCEDURE RetrieveText(aDialog: DialogPtr;
  87.                            anItem: INTEGER;
  88.                            VAR aString: STR255);
  89.  
  90.     PROCEDURE SetText(aDialog  : DialogPtr;
  91.                       itemNo     : INTEGER;
  92.                       theString: STR255);
  93.  
  94.     {changed for 7.0 and Outline Fonts}
  95.  
  96.     PROCEDURE SetSizeMenu(theDoc: DPtr);
  97.  
  98.     FUNCTION LesserOf(A, B: LONGINT): LONGINT;
  99.         
  100.     FUNCTION GreaterOf(A, B: LONGINT): LONGINT;
  101.         
  102.         FUNCTION DoPageSetup(theDoc:DPtr):BOOLEAN;
  103.  
  104.         FUNCTION CtrlKeyPressed(theEvent : EventRecord): Boolean;
  105.  
  106.         FUNCTION OptionKeyPressed(theEvent : EventRecord): Boolean;
  107.  
  108.   IMPLEMENTATION
  109.         
  110.         USES AppleEvents;
  111.         
  112. {*-----------------------------------------------------------------------
  113.         Name:             LesserOf
  114.         Purpose:        Returns the Lesser of two longints.
  115.     -----------------------------------------------------------------------*}
  116.     {$S Utils}
  117.         
  118.     FUNCTION LesserOf(A, B: LONGINT): LONGINT;
  119.  
  120.       BEGIN        (*LesserOf*)
  121.         IF (A < B) THEN
  122.           LesserOf := A
  123.         ELSE
  124.           LesserOf := B;
  125.       END;         (*LesserOf*)
  126.             
  127. {*-----------------------------------------------------------------------
  128.         Name:             GreaterOf
  129.         Purpose:        Returns the Greater of two longints.
  130.     -----------------------------------------------------------------------*}
  131.     {$S Utils}
  132.         
  133.     FUNCTION GreaterOf(A, B: LONGINT): LONGINT;
  134.  
  135.       BEGIN        (*GreaterOf*)
  136.         IF (A > B) THEN
  137.           GreaterOf := A
  138.         ELSE
  139.           GreaterOf := B;
  140.       END;         (*GreaterOf*)
  141.             
  142. {*-----------------------------------------------------------------------
  143.         Name:             ShowError
  144.         Purpose:        Reports an error to the user as both string and number.
  145.     -----------------------------------------------------------------------*}
  146.     {$S Utils}
  147.         
  148.     PROCEDURE ShowError(theError: STR255;
  149.                         theErrorCode: LONGINT);
  150.  
  151.       VAR
  152.         alertResult : INTEGER;
  153.         theString   : STR255;
  154.                 myErr       : OSErr;
  155.  
  156.       BEGIN
  157.                 myErr := AEInteractWithUser(kAEDefaultTimeOut,
  158.                                                                         NIL,
  159.                                                                         NIL);
  160.                 IF (myErr=noErr) THEN
  161.                     BEGIN
  162.                         SetCursor(arrow);
  163.                         NumtoString(theErrorCode, theString);
  164.                         ParamText(theError, theString, '', '');
  165.                         alertResult := Alert(300, NIL);
  166.                   END;
  167.       END; (* ShowError *)
  168.  
  169. {*-----------------------------------------------------------------------
  170.         Name:             Ours
  171.         Purpose:        Checks the frontmost window belongs to the app.
  172.     -----------------------------------------------------------------------*}
  173.     {$S Utils}
  174.         
  175.     FUNCTION Ours(aWindow: WindowPtr): BOOLEAN;
  176.       BEGIN
  177.         Ours := FALSE;
  178.         
  179.                 IF (aWindow <> NIL) THEN
  180.             IF (WindowPeek(aWindow)^.windowKind = zoomDocProc) THEN
  181.               Ours := TRUE;
  182.                         
  183.       END; (* Ours *)
  184.  
  185. {*-----------------------------------------------------------------------
  186.         Name:             SetShortMenus
  187.         Purpose:        Cuts the menus down to a minimum - Apple File Edit.
  188.                                 Greys out the unavailable options - used when no docs open
  189.     -----------------------------------------------------------------------*}
  190.     {$S Utils}
  191.  
  192.     PROCEDURE SetShortMenus;
  193.  
  194.       BEGIN
  195.         DeleteMenu(fontID);
  196.         DeleteMenu(sizeID);
  197.         DeleteMenu(styleID);
  198.  
  199.         DisableItem(myMenus[fileM], fmClose);
  200.         DisableItem(myMenus[fileM], fmSave);
  201.         DisableItem(myMenus[fileM], fmSaveAs);
  202.         DisableItem(myMenus[fileM], fmRevert);
  203.         DisableItem(myMenus[fileM], fmPrint);
  204.         DisableItem(myMenus[fileM], fmPageSetup);
  205.  
  206.         { now the unnecessary items on the edit menu }
  207.                 
  208.         DisableItem(myMenus[editM], undoCommand);
  209.         DisableItem(myMenus[editM], cutCommand);
  210.         DisableItem(myMenus[editM], copyCommand);
  211.         DisableItem(myMenus[editM], clearCommand);
  212.         DisableItem(myMenus[editM], pasteCommand);
  213.         DisableItem(myMenus[editM], selectAllCommand);
  214.  
  215.         DrawMenuBar;
  216.       END; (* SetShortMenus *)
  217.  
  218. {*-----------------------------------------------------------------------
  219.         Name:             SetLongMenus
  220.         Purpose:        Reinstates the full menu bar - called when first document
  221.                     opened.
  222.     -----------------------------------------------------------------------*}
  223.     {$S Utils}
  224.  
  225.     PROCEDURE SetLongMenus;
  226.  
  227.       BEGIN
  228.         InsertMenu(myMenus[fontM], 0);
  229.         InsertMenu(myMenus[sizeM], 0);
  230.         InsertMenu(myMenus[styleM], 0);
  231.  
  232.         EnableItem(myMenus[fileM], fmClose);
  233.         EnableItem(myMenus[fileM], fmSave);
  234.         EnableItem(myMenus[fileM], fmSaveAs);
  235.         EnableItem(myMenus[fileM], fmRevert);
  236.         EnableItem(myMenus[fileM], fmPrint);
  237.         EnableItem(myMenus[fileM], fmPageSetup);
  238.  
  239.         { now the necessary items on the edit menu -
  240.                   many other items fixed on each pass thru the main event
  241.                     loop or before the window pulled down
  242.                 }
  243.                 
  244.         EnableItem(myMenus[editM], selectAllCommand);
  245.  
  246.         DrawMenuBar;
  247.       END; (* SetLongMenus *)
  248.  
  249. {*-----------------------------------------------------------------------
  250.         Name:             SetStyleMenu
  251.         Purpose:        Sets the style menu checking to reflect the style of the
  252.                     first character of the current selection in the given
  253.                                 document.
  254.     -----------------------------------------------------------------------*}
  255.     {$S Utils}
  256.         
  257.     PROCEDURE SetStyleMenu(theDoc: DPtr);
  258.  
  259.       VAR
  260.         theTStyle     : TextStyle;
  261.         contMode      : INTEGER;
  262.         i             : INTEGER;
  263.                 wasCont                : Boolean;
  264.  
  265.       BEGIN
  266.  
  267.                 contMode := doFace;
  268.                         
  269.                 wasCont := TEContinuousStyle(contMode, theTStyle, theDoc^.theText);
  270.  
  271.                 IF (BAnd(contMode, doFace)<>0) THEN
  272.                     BEGIN
  273.                         CheckItem(myMenus[styleM], cPlain,    (theTStyle.tsFace = []));
  274.                         CheckItem(myMenus[styleM], cBold,     (bold IN theTStyle.tsFace));
  275.                         CheckItem(myMenus[styleM], cItalic,   (italic IN theTStyle.tsFace));
  276.                         CheckItem(myMenus[styleM], cUnderline,(underline IN theTStyle.tsFace));
  277.                         CheckItem(myMenus[styleM], cOutline,  (outline IN theTStyle.tsFace));
  278.                         CheckItem(myMenus[styleM], cShadow,   (shadow IN theTStyle.tsFace));
  279.                         CheckItem(myMenus[styleM], cCondense, (condense IN theTStyle.tsFace));
  280.                         CheckItem(myMenus[styleM], cExtend,   (extend IN theTStyle.tsFace));
  281.                     END
  282.                 ELSE
  283.                     FOR i:= cPlain TO cExtend DO
  284.                         CheckItem(myMenus[styleM], i, FALSE);
  285.       END;
  286.  
  287. {*-----------------------------------------------------------------------
  288.     Name:       SetSizeMenu
  289.     Purpose:    Outline all the items if the current font is an
  290.                 outline font. Check the size of the current selection
  291.   -----------------------------------------------------------------------*}
  292.  
  293.     {$S Utils}
  294.  
  295.     PROCEDURE SetSizeMenu(theDoc: DPtr);
  296.  
  297.       VAR
  298.         i                            : INTEGER;
  299.                 aSize                    : INTEGER;
  300.                 max                     : INTEGER;
  301.         theSize       : LONGINT;
  302.         name          : STR255;
  303.         sizeinMenu    : BOOLEAN;
  304.         oldState      : BOOLEAN;
  305.         numer         : POINT;
  306.         theStyle      : TextStyle;
  307.         contMode      : INTEGER;
  308.         wasCont       : Boolean;
  309.  
  310.       BEGIN
  311.         numer.h := 1;
  312.         numer.v := 1;
  313.  
  314.                 contMode := doSize+doFont;
  315.                 
  316.                 wasCont := TEContinuousStyle(contMode, theStyle, theDoc^.theText);
  317.         
  318.  
  319.         sizeinMenu := FALSE;
  320.         max := CountMItems(myMenus[sizeM]);
  321.         FOR i := 1 TO max - 5 DO
  322.           BEGIN
  323.             GetItem(myMenus[sizeM], i, name);
  324.             StringtoNum(name, theSize);
  325.             aSize := theSize;
  326.  
  327.             IF RealFont(theStyle.tsFont, aSize) AND (BAnd(contMode, doFont) <> 0) THEN
  328.               SetItemStyle(myMenus[sizeM], i, [outline])
  329.             ELSE
  330.               SetItemStyle(myMenus[sizeM], i, []);
  331.  
  332.             IF ((aSize = theStyle.tsSize) AND (BAnd(contMode, doSize) <> 0)) THEN
  333.               BEGIN
  334.                 sizeinMenu := TRUE;
  335.                 CheckItem(myMenus[sizeM], i, TRUE);
  336.               END
  337.             ELSE
  338.               CheckItem(myMenus[sizeM], i, FALSE);
  339.           END;
  340.                     
  341.                 {
  342.                     if it's not a size in the menu,and there is only one size in the
  343.                     selection range check the other item
  344.                 }
  345.             
  346.               IF ((NOT sizeinMenu) AND (BAnd(contMode, doSize) <> 0)) THEN
  347.           CheckItem(myMenus[sizeM], max, TRUE)
  348.         ELSE
  349.           CheckItem(myMenus[sizeM], max, FALSE);
  350.  
  351.         {if this is an outline font, set the rest of the items to outline style}
  352.         {RealFont will ensure that the sizes are outlined}
  353.  
  354.         oldState := GetOutlinePreferred;
  355.         SetOutlinePreferred(TRUE);
  356.         FOR i := max - 4 TO max DO
  357.           BEGIN
  358.             IF IsOutline(numer, numer) AND (BAnd(contMode, doFont)<>0) THEN
  359.               SetItemStyle(myMenus[sizeM], i, [outline])
  360.             ELSE
  361.               SetItemStyle(myMenus[sizeM], i, []);
  362.           END;
  363.         SetOutlinePreferred(oldState);
  364.       END;
  365.  
  366. {*-----------------------------------------------------------------------
  367.     Name:       SetEditMenu
  368.     Purpose:    Set the text of the edit menu according to the state of
  369.                                 current document.
  370.   -----------------------------------------------------------------------*}
  371.  
  372.     {$S Utils}
  373.     PROCEDURE SetEditMenu(theDoc: DPtr);
  374.       BEGIN
  375.                 IF theDoc^.showBorders THEN
  376.                     SetItem(myMenus[editM], cBorders, 'Hide Borders')
  377.                 ELSE
  378.                     SetItem(myMenus[editM], cBorders, 'Show Borders');
  379.       END; (* SetEditMenu *)
  380.             
  381. {*-----------------------------------------------------------------------
  382.     Name:       SetFontMenu
  383.     Purpose:    Set the font menu according to the state of
  384.                                 current selection of the supplied document.
  385.   -----------------------------------------------------------------------*}
  386.  
  387.     {$S Utils}
  388.         
  389.     PROCEDURE SetFontMenu(theDoc: DPtr);
  390.  
  391.       VAR
  392.         theMHandle    : MenuHandle;
  393.         theNumber     : INTEGER;
  394.         i             : INTEGER;
  395.         max           : INTEGER;
  396.         name          : STR255;
  397.         theStyle      : TextStyle;
  398.         contMode      : INTEGER;
  399.                 wasCont       : Boolean;
  400.                 
  401.       BEGIN
  402.         theMHandle := GetMHandle(fontID);
  403.         IF gFontMItem <> 0 THEN
  404.           CheckItem(theMHandle, gFontMItem, FALSE);
  405.                     
  406.         max := CountMItems(theMHandle);
  407.         conTMode := doFont;
  408.                 
  409.                 wasCont := TEContinuousStyle(contMode, theStyle, theDoc^.theText);
  410.             
  411.                 gFontMItem := 0;
  412.         
  413.                 IF (BAnd(contMode, doFont)<>0) THEN
  414.                     FOR i := 1 TO max DO
  415.                         BEGIN
  416.                             GetItem(theMHandle, i, name);
  417.                             GetFNum(name, theNumber);
  418.                             IF theNumber = theStyle.tsFont THEN
  419.                                 gFontMItem := i;
  420.                         END;
  421.  
  422.         IF gFontMItem <> 0 THEN
  423.           CheckItem(theMHandle, gFontMItem, TRUE);
  424.         SetSizeMenu(theDoc);
  425.         SetStyleMenu(theDoc);
  426.       END;
  427.  
  428. {*-----------------------------------------------------------------------
  429.     Name:       GetTempFileName
  430.     Purpose:    Fills newstring with a temporary file name.
  431.   -----------------------------------------------------------------------*}
  432.  
  433.     {$S Utils}
  434.     PROCEDURE GetTempFileName(aDoc: DPtr;
  435.                               VAR newString: STR255);
  436.  
  437.       VAR
  438.         s             : STR255;
  439.         time          : LONGINT;
  440.         filename      : STR255;
  441.  
  442.       BEGIN
  443.         IF (aDoc^.everSaved = false) THEN
  444.           filename := 'TEXTra'
  445.         ELSE
  446.           filename := aDoc^.theFileName;
  447.  
  448.         {generate a unique(ish) temporary filename}
  449.         IF Length(filename) > 21 THEN
  450.           filename := Copy(filename, 1, 21);
  451.  
  452.         GetDateTime(time);
  453.         NumtoString(ABS(BXOR(time, BRotR(TickCount, 16))), s);
  454.         filename := CONCAT(filename, s);
  455.         newString := filename;
  456.       END;
  457.  
  458. {*-----------------------------------------------------------------------
  459.     Name:       SetText
  460.     Purpose:    Sets the text of the supplied itemNo in aDialog to 
  461.                                 theString and select it.
  462.   -----------------------------------------------------------------------*}
  463.  
  464.     {$S Utils}
  465.     PROCEDURE SetText(aDialog  : DialogPtr;
  466.                       itemNo     : INTEGER;
  467.                       theString: STR255);
  468.  
  469.       VAR
  470.         itemHandle    : Handle;
  471.         box           : Rect;
  472.         kind          : INTEGER;
  473.         theTeHandle   : TEHandle;
  474.  
  475.       BEGIN
  476.         GetDItem(aDialog, itemNo, kind, itemHandle, box);
  477.         SetItext(itemHandle, theString);
  478.         theTeHandle := DialogPeek(aDialog)^.textH;
  479.  
  480.         {set all the text to be selected}
  481.         IF theTeHandle <> NIL THEN
  482.           TESetSelect(0, 255, theTeHandle);
  483.       END;
  484.             
  485. {*-----------------------------------------------------------------------
  486.     Name:       RetrieveText
  487.     Purpose:    Returns the text of anItem in aDialog in aString.
  488.   -----------------------------------------------------------------------*}
  489.  
  490.     {$S Utils}
  491.  
  492.     PROCEDURE RetrieveText(aDialog        : DialogPtr;
  493.                            anItem            : INTEGER;
  494.                            VAR aString: STR255);
  495.  
  496.       VAR
  497.         kind          : INTEGER;
  498.         box           : Rect;
  499.         itemHandle    : Handle;
  500.  
  501.       BEGIN
  502.         GetDItem(aDialog, anItem, kind, itemHandle, box);
  503.         GetIText(itemHandle, aString);
  504.       END;
  505.  
  506. {*-----------------------------------------------------------------------
  507.     Name:       DrawDefaultOutline
  508.     Purpose:    Draws an outline around theItem.
  509.                                 Called as a useritem Proc by the dialog manager.
  510.                                 To use place a useritem over the default item in the
  511.                                 dialog and install the address of this proc as the item
  512.                                 handle.
  513.   -----------------------------------------------------------------------*}
  514.  
  515.     {$S Utils}
  516.         
  517.         PROCEDURE DrawDefaultOutline(theDialog:DialogPtr; theItem:INTEGER);
  518.       VAR
  519.         kind          : INTEGER;
  520.         itemHandle    : Handle;
  521.         box           : Rect;
  522.                 
  523.             BEGIN
  524.         GetDItem(theDialog, theItem, kind, itemHandle, box);
  525.         PenSize(3, 3);
  526.         InsetRect(box, - 4, - 4);
  527.         FrameRoundRect(box, 16, 16);
  528.         PenNormal;
  529.             END; (* DrawDefaultOutline *)
  530.             
  531. {*-----------------------------------------------------------------------
  532.     Name:       AdornDefaultButton
  533.     Purpose:    Installs DrawDefaultOutline as the useritem proc
  534.                     for the given item.
  535.   -----------------------------------------------------------------------*}
  536.  
  537.     {$S Utils}
  538.         
  539.     PROCEDURE AdornDefaultButton(theDialog: DialogPtr; theItem:INTEGER);
  540.  
  541.       VAR
  542.         kind          : INTEGER;
  543.         itemHandle    : Handle;
  544.         box           : Rect;
  545.  
  546.       BEGIN
  547.         GetDItem(theDialog, theItem, kind, itemHandle, box);
  548.         SetDItem(theDialog, theItem, kind, @DrawDefaultOutline, box);
  549.       END;
  550.  
  551.     {-------  Determining of Gestalt is available ---------------}
  552.     {The following routines come from the Inside Mac VI recommendations}
  553.     {about how to find if a trap is available}
  554.          {
  555.             The glue for Gestalt will be in MPW 3.2, so if it is available we will also
  556.              need to check the system version
  557.         }
  558.         PROCEDURE GetRectOfDialogItem(theDialog : DialogPtr; theItem:INTEGER; VAR theRect:Rect);
  559.             VAR
  560.                 kind       : INTEGER;
  561.                 itemHandle : Handle;
  562.                 
  563.             BEGIN
  564.                 GetDItem(theDialog, theItem, kind, itemHandle, theRect);
  565.             END;
  566.  
  567.     {$S Utils}
  568.  
  569.     FUNCTION NumToolboxTraps: INTEGER;
  570.  
  571.       BEGIN
  572.         IF NGetTrapAddress(_InitGraf, ToolTrap) = NGetTrapAddress($AA6E, ToolTrap) THEN
  573.           NumToolboxTraps := $200
  574.         ELSE
  575.           NumToolboxTraps := $400;
  576.       END;
  577.  
  578.     {$S Utils}
  579.  
  580.     FUNCTION GetTrapType(theTrap: INTEGER): TrapType;
  581.  
  582.       CONST
  583.         TrapMask       = $0800;
  584.  
  585.       BEGIN
  586.         IF BAND(theTrap, TrapMask) > 0 THEN
  587.           GetTrapType := ToolTrap
  588.         ELSE
  589.           GetTrapType := OSTrap;
  590.       END;
  591.  
  592.     {$S Utils}
  593.  
  594.     FUNCTION TrapAvailable(theTrap: INTEGER): BOOLEAN;
  595.  
  596.       VAR
  597.         tType         : TrapType;
  598.  
  599.       BEGIN
  600.         tType := GetTrapType(theTrap);
  601.         IF tType = ToolTrap THEN
  602.           BEGIN
  603.             theTrap := BAND(theTrap, $07FF);
  604.             IF theTrap >= NumToolboxTraps THEN
  605.               theTrap := _Unimplemented;
  606.           END;
  607.         TrapAvailable := NGetTrapAddress(theTrap, tType) <> NGetTrapAddress(_Unimplemented,
  608.                          ToolTrap);
  609.       END;
  610.  
  611.     {$S Utils}
  612.  
  613.     FUNCTION GestaltAvailable: BOOLEAN;
  614.  
  615.       CONST
  616.         _Gestalt       = $A1AD;
  617.  
  618.       BEGIN
  619.         GestaltAvailable := TrapAvailable(_Gestalt);
  620.       END;
  621.  
  622.     {*------  FeatureIsImplemented    ------------*}
  623.         {This is called to use Gestalt to determine if a feature is implemented.
  624.           This applies to only those referenced by OSType}
  625.  
  626.     {$S Utils}
  627.  
  628.     FUNCTION FeatureIsImplemented(theFeature: OSType;
  629.                                   theTestBit: INTEGER): BOOLEAN;
  630.  
  631.       VAR
  632.         err           : OSErr;
  633.         result        : LONGINT;
  634.  
  635.       BEGIN
  636.         FeatureIsImplemented := FALSE;
  637.         err := Gestalt(theFeature, result);
  638.         IF err = noErr THEN
  639.           IF BitTst(@result, 31 -theTestBit) = TRUE THEN
  640.             FeatureIsImplemented := TRUE;
  641.       END;
  642.  
  643.     {$S Utils}
  644.  
  645.     FUNCTION CheckEnvironment: BOOLEAN;
  646.       BEGIN
  647.         CheckEnvironment := TRUE;
  648.                 (*
  649.                  first determine of Gestalt is available- if it isn't exit
  650.                  as we only run under 7.0.  It could it present in 6.04 - so we need
  651.                  to do some further checks for important features
  652.                 *)
  653.  
  654.         gGestaltAvailable := GestaltAvailable;
  655.         IF NOT gGestaltAvailable THEN
  656.           BEGIN
  657.                         CheckEnvironment := FALSE;
  658.                         Exit(CheckEnvironment);
  659.                     END;
  660.  
  661.         {first check if the Edition Manager is present}
  662.                 
  663.         gEditionManagerImplemented:= FeatureIsImplemented(gestaltEditionMgrAttr,
  664.                                                                                                                     gestaltEditionMgrPresent);
  665.  
  666.         {and for good measure- the Alias manager}
  667.                 
  668.         gAliasManagerImplemented  := FeatureIsImplemented(gestaltAliasMgrAttr,
  669.                                                                                                                     gestaltAliasMgrPresent);
  670.                     
  671.                 {check for the AppleEvents manager - we certainly can't work without it}
  672.                 
  673.         gAppleEventsImplemented   := FeatureIsImplemented(gestaltAppleEventsAttr,
  674.                                                                                                                   gestaltAppleEventsPresent);
  675.                     
  676.                 {check for the Outline fonts}
  677.                 
  678.         gOutlineFontsImplemented  := FeatureIsImplemented(gestaltFontMgrAttr,
  679.                                                                                                                     gestaltOutlineFonts);
  680.                                                                                                                     
  681.                 {check to see if recording is implemented. Set the flag only}
  682.                 gRecordingImplemented := FeatureIsImplemented(gestaltAppleEventsAttr,
  683.                                                                                                                     1);
  684.                 
  685.                 CheckEnvironment := gEditionManagerImplemented AND
  686.                                                         gAliasManagerImplemented   AND
  687.                                                         gAppleEventsImplemented    AND
  688.                                                         gOutlineFontsImplemented;
  689.                                         
  690.       END; (* CheckEnvironment *)
  691.             
  692.     (*
  693.         DoPageSetup returns true if the page setup of the document is altered
  694.     *)
  695.     
  696.         FUNCTION DoPageSetup(theDoc:DPtr):BOOLEAN;
  697.             BEGIN
  698.                 DoPageSetup := FALSE;
  699.                 
  700.                 IF (theDoc<>NIL) THEN
  701.                     BEGIN
  702.                         PrOpen;
  703.                         DoPageSetup:=  PrStlDialog(theDoc^.thePrintSetup);
  704.                         PrClose;
  705.                     END;
  706.             END; (* DoPageSetup *)
  707.  
  708. (*
  709.     Name:    CtrlKeyPressed
  710.     Purpose: Returns true if control key pressed during event
  711. *)
  712. FUNCTION CtrlKeyPressed(theEvent : EventRecord): Boolean;
  713.     BEGIN
  714.         CtrlKeyPressed := (BAnd(theEvent.modifiers, controlKey) <> 0);
  715.     END;
  716.     
  717. (*
  718.     Name:    OptionKeyPressed
  719.     Purpose: Returns true if option key pressed during event
  720. *)
  721.  
  722. FUNCTION OptionKeyPressed(theEvent : EventRecord): Boolean;
  723.     BEGIN
  724.         OptionKeyPressed:= (BAnd(theEvent.modifiers, optionKey) <> 0);
  725.     END;
  726.  
  727. END.
  728.